package com.example.ssd4.view;

import com.example.ssd4.domain.Lesson;
import com.example.ssd4.domain.LessonLbl;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.Event;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.VPos;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;
import javafx.util.converter.DefaultStringConverter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class StudentDialog extends Application {
    private static Stage thisStage;
    private Scene scene;
    private String account;
    private VBox mainVBox;
    private TableView<Lesson> allLessonsTable;
    private ObservableList<Lesson> allLessonsList;
    private TableView<Lesson> chosenLessonsTable;
    private ObservableList<Lesson> chosenLessonsList;
    private Button returnBtn;
    private Button searchBtn;
    private Button resetBtn;
    private Button selectBtn;
    private Button removeBtn;
    private TextField nameSearch;
    private TextField teacherSearch;
    private ComboBox<String> attributeCb;
    private CheckBox hideCb;
    private CheckBox conflictCb;
    private ComboBox<String> dayCb;
    private ComboBox<String> timeCb;
    private GridPane tablePane = new GridPane();
    private Map<String,LessonLbl> lessonLblMap = new HashMap<>();

    @Override
    public void start(Stage stage) throws Exception {
        mainVBox = new VBox();
        scene = new Scene(mainVBox,817,550);
        LoginDialog.addGlobalShortcut(scene);
        thisStage = stage;

        initGraphic();
        initAction();

        stage.setResizable(false);
        stage.setScene(scene);
        stage.show();
    }

    private void initGraphic() {
        //title
        HBox titleHBox = new HBox();
        HBox titleLeft = new HBox();
        mainVBox.getChildren().add(titleHBox);

        Label label = new Label(" 本科教务系统");
        label.setFont(Font.font("微软雅黑", FontWeight.BOLD,25));
        Image image = new Image("file:src/main/resources/image/logo3_proc.jpg");
        ImageView imageView = new ImageView(image);
        titleLeft.getChildren().addAll(imageView,label);
        returnBtn = new Button("返回登录");
        returnBtn.setStyle(
                "-fx-pref-width: 100px;-fx-pref-height: 20px;"+
                        "-fx-background-color: #FF0060;"+
                        "-fx-border-radius: 60px;"+
                        "-fx-font-size: 10px;"+
                        "-fx-text-fill: WHITE;"+
                        "-fx-font-weight: bold;");


        titleHBox.setPadding(new Insets(0,10,0,10));
        titleHBox.setSpacing(430);
        titleHBox.setAlignment(Pos.CENTER_LEFT);
        titleHBox.getChildren().addAll(titleLeft,returnBtn);

        //tab
        TabPane tabPane = new TabPane();
        Tab lessonTab = new Tab("全部课程");
        Tab myTab = new Tab("我的课程");
        Tab tableTab = new Tab("我的课表");
        tabPane.getTabs().addAll(lessonTab,myTab,tableTab);
        mainVBox.getChildren().add(tabPane);

        VBox lessonVBox = new VBox();
        VBox myVBox = new VBox();
        VBox tableVBox = new VBox();
        lessonTab.setContent(lessonVBox);
        myTab.setContent(myVBox);
        tableTab.setContent(tableVBox);
        lessonTab.setClosable(false);
        myTab.setClosable(false);
        tableTab.setClosable(false);

        //lessonTab
        {
            allLessonsTable = new TableView<>();
            allLessonsList = FXCollections.observableArrayList();
            List<Lesson> lessons = Lesson.readFromLogFile("src\\main\\resources\\data\\lesson.log");
            allLessonsList.addAll(lessons);
            allLessonsTable.setItems(allLessonsList);

            initTable(allLessonsTable);
            lessonVBox.getChildren().add(allLessonsTable);

            //search
            GridPane gridPane = new GridPane();
            lessonVBox.getChildren().add(gridPane);
            gridPane.setHgap(10);
            gridPane.setVgap(10);

            nameSearch = new TextField();
            gridPane.add(new Label("课程名:"),0,0);
            gridPane.add(nameSearch,1,0);
            gridPane.setPadding(new Insets(10));

            Label placeHolder_1 = new Label("");
            placeHolder_1.setMinWidth(50);
            gridPane.add(placeHolder_1,2,0);
            Label placeHolder_2 = new Label("");
            placeHolder_2.setMinWidth(50);
            gridPane.add(placeHolder_2,5,0);

            teacherSearch = new TextField();
            gridPane.add(new Label("教师:"),3,0);
            gridPane.add(teacherSearch,4,0);

            attributeCb = new ComboBox<>();
            attributeCb.getItems().addAll("全部","选修","公选");
            attributeCb.getSelectionModel().select(0);
            gridPane.add(new Label("课程性质:"),6,0);
            gridPane.add(attributeCb,7,0);

            dayCb = new ComboBox<>();
            dayCb.getItems().addAll("全部星期","周一", "周二", "周三", "周四", "周五");
            dayCb.getSelectionModel().select(0);
            gridPane.add(new Label("星期:"),0,1);
            gridPane.add(dayCb,1,1);

            timeCb = new ComboBox<>();
            timeCb.getItems().addAll("全部节次","0102","0304","0506","0708","0910");
            timeCb.getSelectionModel().select(0);
            gridPane.add(new Label("节次:"),3,1);
            gridPane.add(timeCb,4,1);

            hideCb = new CheckBox();
            hideCb.setText("隐藏已选择的课程");
            GridPane.setColumnSpan(hideCb,2);
            gridPane.add(hideCb,6,1);

            conflictCb = new CheckBox();
            conflictCb.setText("隐藏时间冲突的课程");
            GridPane.setColumnSpan(conflictCb,2);
            gridPane.add(conflictCb,6,2);

            HBox buttonHBox = new HBox();
            buttonHBox.setSpacing(20);
            searchBtn = new Button("搜索");
            searchBtn.setGraphic(new ImageView("file:src/main/resources/image/search.png"));
            searchBtn.setStyle(
                    "-fx-pref-width: 60px;-fx-pref-height: 10px;"+
                            "-fx-background-color: #2020A0;"+
                            "-fx-border-radius: 60px;"+
                            "-fx-font-size: 10px;"+
                            "-fx-text-fill: WHITE;"+
                            "-fx-font-weight: bold;");
            resetBtn = new Button("重置");
            resetBtn.setGraphic(new ImageView("file:src/main/resources/image/reset.png"));
            resetBtn.setStyle(
                    "-fx-pref-width: 60px;-fx-pref-height: 10px;"+
                            "-fx-background-color: #6aaefc;"+
                            "-fx-border-radius: 60px;"+
                            "-fx-font-size: 10px;"+
                            "-fx-text-fill: BLACK;"+
                            "-fx-font-weight: bold;");
            buttonHBox.getChildren().addAll(searchBtn,resetBtn);
            GridPane.setColumnSpan(buttonHBox,2);
            gridPane.add(buttonHBox,0,2);

            selectBtn = new Button("选择课程");
            selectBtn.setGraphic(new ImageView("file:src/main/resources/image/select.png"));
            selectBtn.setStyle(
                    "-fx-pref-width: 120px;-fx-pref-height: 10px;"+
                            "-fx-background-color: #2bda82;"+
                            "-fx-border-radius: 60px;"+
                            "-fx-font-size: 10px;"+
                            "-fx-text-fill: BLACK;"+
                            "-fx-font-weight: bold;");
            GridPane.setColumnSpan(selectBtn,2);
            gridPane.add(selectBtn,3,2);
        }

        //chooseTab
        {
            chosenLessonsTable = new TableView<>();
            chosenLessonsList = FXCollections.observableArrayList();
            List<Lesson> lessons = Lesson.readFromLogFile("src\\main\\resources\\data\\student\\" + account + ".log");
            chosenLessonsList.addAll(lessons);
            chosenLessonsTable.setItems(chosenLessonsList);
            addLessonLbl(lessons);

            initTable(chosenLessonsTable);
            myVBox.getChildren().add(chosenLessonsTable);

            HBox buttonHBox = new HBox();
            removeBtn = new Button("退选课程");
            removeBtn.setGraphic(new ImageView("file:src/main/resources/image/quit.png"));
            removeBtn.setStyle(
                    "-fx-pref-width: 120px;-fx-pref-height: 30px;"+
                            "-fx-border-radius: 60px;"+
                            "-fx-font-size: 15px;"+
                            "-fx-font-weight: bold;");
            buttonHBox.getChildren().addAll(removeBtn);
            buttonHBox.setAlignment(Pos.CENTER);
            buttonHBox.setPadding(new Insets(20));
            myVBox.getChildren().addAll(buttonHBox);
        }

        //tableTab
        Label[] head = new Label[8];
        String[] weekDays = {"周日", "周一", "周二", "周三", "周四", "周五", "周六"};
        Label[] side = new Label[5];
        String[] times = {"01-02","03-04","05-06","07-08","09-10"};

        for (int i = 0; i < 8; i++){
            if(i == 0){
                head[0] = new Label("");
                head[i].setMinWidth(75);
            }else {
                head[i] = new Label(weekDays[i-1]);
                head[i].setMinWidth(106);
            }
            head[i].setMinHeight(50);

            head[i].setStyle("-fx-background-color: #e3e3e3;");
            head[i].setAlignment(Pos.CENTER); // 居中对齐
            head[i].setFont(new Font("Microsoft YaHei", 16)); // 设置字体和大小

            tablePane.add(head[i], i, 0); // 将标签添加到网格面板中
        }

        for (int i = 0; i < 5; i++){
            side[i] = new Label(times[i]);

            side[i].setMinWidth(75);
            side[i].setMinHeight(80);
            side[i].setAlignment(Pos.CENTER); // 居中对齐
            side[i].setFont(new Font("Microsoft YaHei", 16)); // 设置字体和大小

            tablePane.add(side[i],0,i + 1);
        }

        tableVBox.getChildren().add(tablePane);
    }

    private void addLessonLbl(ObservableList<Lesson> lessons){
        for(Lesson lesson : lessons){
            String[] records = lesson.getTime().split(" ")[1].split(",");
            for(String record : records){
                String dayStr = record.split("-")[0];
                String timeStr = record.split("-")[1].substring(1,2);
                int day = Integer.parseInt(dayStr) % 7 + 1;
                int time = (Integer.valueOf(timeStr) + 1) / 2;

                LessonLbl lessonLbl = new LessonLbl(lesson,day);

                String str = lesson.getId() + day + time;
                tablePane.add(lessonLbl,day,time);
                lessonLblMap.put(str,lessonLbl);
            }
        }
    }

    private void addLessonLbl(List<Lesson> lessons){
        for(Lesson lesson : lessons){
            String[] records = lesson.getTime().split(" ")[1].split(",");
            for(String record : records){
                String dayStr = record.split("-")[0];
                String timeStr = record.split("-")[1].substring(1,2);
                int day = Integer.parseInt(dayStr) % 7 + 1;
                int time = (Integer.valueOf(timeStr) + 1) / 2;

                LessonLbl lessonLbl = new LessonLbl(lesson,day);

                String str = lesson.getId() + day + time;
                tablePane.add(lessonLbl,day,time);
                lessonLblMap.put(str,lessonLbl);
            }
        }
    }

    private void removeLessonLbl(ObservableList<Lesson> lessons){
        for(Lesson lesson : lessons){
            String[] records = lesson.getTime().split(" ")[1].split(",");
            for(String record : records) {
                String dayStr = record.split("-")[0];
                String timeStr = record.split("-")[1].substring(1, 2);
                int day = Integer.parseInt(dayStr) % 7 + 1;
                int time = (Integer.valueOf(timeStr) + 1) / 2;
                String str = lesson.getId() + day + time;

                tablePane.getChildren().remove(lessonLblMap.get(str));
            }
        }
    }

    private void initTable(TableView tableView){
        tableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
        TableColumn<Lesson, String> idColumn = new TableColumn<>("ID");
        TableColumn<Lesson, String> nameColumn = new TableColumn<>("Name");
        TableColumn<Lesson, String> timeColumn = new TableColumn<>("Time");
        TableColumn<Lesson, String> teacherColumn = new TableColumn<>("Teacher");
        TableColumn<Lesson, String> scoreColumn = new TableColumn<>("Score");
        TableColumn<Lesson, String> creditColumn = new TableColumn<>("Credit");
        TableColumn<Lesson, String> attributeColumn = new TableColumn<>("Attribute");
        TableColumn<Lesson, String> capacityColumn = new TableColumn<>("Capacity");

        idColumn.setCellValueFactory(new PropertyValueFactory<>("id"));
        nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
        timeColumn.setCellValueFactory(new PropertyValueFactory<>("time"));
        teacherColumn.setCellValueFactory(new PropertyValueFactory<>("teacher"));
        scoreColumn.setCellValueFactory(new PropertyValueFactory<>("score"));
        creditColumn.setCellValueFactory(new PropertyValueFactory<>("credit"));
        attributeColumn.setCellValueFactory(new PropertyValueFactory<>("attribute"));
        capacityColumn.setCellValueFactory(new PropertyValueFactory<>("capacity"));

        idColumn.setMinWidth(80);
        nameColumn.setMinWidth(180);
        timeColumn.setMinWidth(200);
        teacherColumn.setMinWidth(80);
        scoreColumn.setMinWidth(80);
        creditColumn.setMinWidth(50);
        attributeColumn.setMinWidth(50);
        capacityColumn.setMinWidth(50);

        // 将列添加到TableView
        tableView.getColumns().addAll(idColumn, nameColumn, timeColumn, teacherColumn, scoreColumn, creditColumn, attributeColumn, capacityColumn);
    }

    private void initAction() {
        returnBtn.setOnAction(actionEvent -> {
            try {
                LoginDialog.thisStage.show();
                thisStage.close();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        });

        searchBtn.setOnAction(actionEvent -> {
            String nameValue = nameSearch.getText().trim();
            String teacherValue = teacherSearch.getText().trim();
            String dayValue = dayCb.getValue();
            String attributeValue = attributeCb.getValue();
            String timeValue = timeCb.getValue();
            boolean hideValue = hideCb.isSelected();
            boolean conflictValue = conflictCb.isSelected();

            List<Lesson> result = Lesson.readFromLogFile("src\\main\\resources\\data\\lesson.log");
            if (!nameValue.isEmpty()) {
                result = Lesson.findLessonsByName(result, nameValue);
            }
            if (!teacherValue.isEmpty()) {
                result = Lesson.findLessonsByTeacher(result, teacherValue);
            }
            if (!dayValue.equals("全部星期")) {
                result = Lesson.findLessonsByDay(result, dayValue);
            }
            if (!attributeValue.equals("全部")) {
                result = Lesson.findLessonsByAttribute(result, attributeValue);
            }
            if (!timeValue.equals("全部节次")) {
                result = Lesson.findLessonsByTime(result, timeValue);
            }
            if (hideValue) {
                List<Lesson> alreadySelectedLessons = Lesson.readFromLogFile("src\\main\\resources\\data\\student\\" + account + ".log");
                result.removeIf(alreadySelectedLessons::contains);
            }
            if (conflictValue) {
                List<Lesson> alreadySelectedLessons = Lesson.readFromLogFile("src\\main\\resources\\data\\student\\" + account + ".log");
                result.removeIf(lesson -> alreadySelectedLessons.stream().anyMatch(selectedLesson -> Lesson.isTimeConflict(lesson, selectedLesson)));
            }

            allLessonsList.clear();
            allLessonsList.addAll(result);
        });

        resetBtn.setOnAction(actionEvent -> {
            nameSearch.setText("");
            teacherSearch.setText("");
            dayCb.getSelectionModel().select(0);
            attributeCb.getSelectionModel().select(0);
            timeCb.getSelectionModel().select(0);

            searchBtn.fire();
            nameSearch.requestFocus();
        });

        selectBtn.setOnAction(actionEvent -> {
            ObservableList<Lesson> selectedLessons = allLessonsTable.getSelectionModel().getSelectedItems();

            for (int i = 0; i < selectedLessons.size(); i++) {
                for (int j = i + 1; j < selectedLessons.size(); j++) {
                    Lesson lesson1 = selectedLessons.get(i);
                    Lesson lesson2 = selectedLessons.get(j);

                    // 使用您的isTimeConflict方法检查冲突
                    if (Lesson.isTimeConflict(lesson1, lesson2)) {
                        System.out.println("发现冲突: " + lesson1 + " 和 " + lesson2);
                        Alert alert = new Alert(Alert.AlertType.INFORMATION);
                        alert.setTitle("选择课程");
                        alert.setHeaderText("选择课程：");
                        alert.setContentText(lesson1.getName() + " 与 "  + lesson2.getName() +" 选课冲突，请重新选择!");
                        alert.showAndWait();
                        return;
                    }
                }
            }

            List<Lesson> modifyLessons = new ArrayList<>(selectedLessons);

            List<Lesson> alreadySelectedLessons = Lesson.readFromLogFile("src\\main\\resources\\data\\student\\" + account + ".log");
            List<Lesson> finalAlreadySelectedLessons = alreadySelectedLessons;
            boolean removed = modifyLessons.removeIf(lesson -> finalAlreadySelectedLessons.stream().anyMatch(selectedLesson -> Lesson.isTimeConflict(lesson, selectedLesson)));
            if (removed) {
                Alert alert = new Alert(Alert.AlertType.INFORMATION);
                alert.setTitle("选择课程");
                alert.setHeaderText("选择课程：");
                alert.setContentText("您选择的课程与已选择选课冲突，请重新选择!");
                alert.showAndWait();
                return;
            }

            if (!selectedLessons.isEmpty()) {
                String msg = Lesson.writeSelectedLessonsToFile(selectedLessons, "src\\main\\resources\\data\\student\\" + account + ".log");
                if (!msg.equals("已经被选择！")) {
                    Alert alert = new Alert(Alert.AlertType.WARNING);
                    alert.setTitle("选择课程");
                    alert.setHeaderText("选择课程：");
                    alert.setContentText(msg);
                    alert.showAndWait();
                } else {
                    Alert alert = new Alert(Alert.AlertType.INFORMATION);
                    alert.setTitle("选择课程");
                    alert.setHeaderText("选择课程：");
                    alert.setContentText("选择成功!");
                    alert.showAndWait();
                }
            }

            alreadySelectedLessons = Lesson.readFromLogFile("src\\main\\resources\\data\\student\\" + account + ".log");
            chosenLessonsList.clear();
            chosenLessonsList.addAll(alreadySelectedLessons);
            addLessonLbl(modifyLessons);

        });

        removeBtn.setOnAction(actionEvent -> {
            ObservableList<Lesson> selectedLessons = chosenLessonsTable.getSelectionModel().getSelectedItems();

            if (!selectedLessons.isEmpty()) {
                // 创建并配置一个确认对话框
                Alert confirmAlert = new Alert(Alert.AlertType.CONFIRMATION);
                confirmAlert.setTitle("退选课程");
                confirmAlert.setHeaderText("确认退选");
                confirmAlert.setContentText("确定要退选选中的课程吗？");

                // 显示对话框并等待用户响应
                confirmAlert.showAndWait().ifPresent(response -> {
                    if (response == ButtonType.OK) {
                        // 用户确认退选
                        List<Lesson> alreadySelectedLessons = Lesson.readFromLogFile("src\\main\\resources\\data\\student\\" + account + ".log");
                        Lesson.removeSelectedLessons(alreadySelectedLessons, new ArrayList<>(selectedLessons), "src\\main\\resources\\data\\student\\" + account + ".log");
                        chosenLessonsList.removeAll(selectedLessons);
                        removeLessonLbl(selectedLessons);
                    }
                });
            }
        });

        nameSearch.setOnAction(actionEvent -> {
            teacherSearch.requestFocus();
            searchBtn.fire();
        });
        teacherSearch.setOnAction(actionEvent -> {
            attributeCb.requestFocus();
            attributeCb.show();
            searchBtn.fire();
        });
        attributeCb.setOnAction(actionEvent -> {
            dayCb.requestFocus();
            dayCb.show();
        });
        dayCb.setOnAction(actionEvent -> {
            timeCb.requestFocus();
            timeCb.show();
        });
        timeCb.setOnAction(actionEvent -> {
            hideCb.requestFocus();
        });
        hideCb.setOnAction(actionEvent -> {
            conflictCb.requestFocus();
            searchBtn.fire();
        });
        conflictCb.setOnAction(actionEvent -> {
            searchBtn.requestFocus();
            searchBtn.fire();
        });

        scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
            if (event.getCode() == KeyCode.S && event.isControlDown()) {
                searchBtn.fire();
                event.consume();
            }
        });
        scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
            if (event.getCode() == KeyCode.R && event.isControlDown()) {
                resetBtn.fire();
                event.consume();
            }
        });
        scene.addEventFilter(KeyEvent.KEY_PRESSED, event -> {
            if (event.getCode() == KeyCode.C && event.isControlDown()) {
                selectBtn.fire();
                event.consume();
            }
        });

    }

    public void initAccount(String account){
        this.account = account;
    }

}
